﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Code.Models;
using Code.Commen;

namespace Code.BLL
{
    public class ChaseManage:ManageBase<ChaseTask>
    {
        /// <summary>
        /// 添加追号任务
        /// </summary>
        /// <exception cref="System.ArgumentNullException"/>
        /// <exception cref="Code.Models.ValidateException"/>
        /// <exception cref="Code.Models.AppException"/>
        public int AddChaseTask(ChaseTask task,IEnumerable<Scheme_Detail> plays, IEnumerable<ChaseTask_Detail> details)
        {
            int rs = -1;
           
            if (task == null)
                throw new ArgumentNullException("task");
            else if (details == null || details.Count() == 0)
                throw new ArgumentNullException("details");

            var user = base.Select<Users, Users>(s => s.FirstOrDefault(p => p.ID == task.UserID));
            if (user == null)
                throw new ValidateException("用户不存在");

            var maxchasetask = CacheManage.OptionSite[Option_Site_Key.User_MaxChaseTaskMun].ToInt32(400);
            var forwarend=CacheManage.Lottery[(LotteryType)task.LotteryID].ForwardEnd;
            var issues = base.Select<Issue,IEnumerable<long>>(s => s.Where(p => p.LotteryID == task.LotteryID && p.EndTime > DateTime.Now.AddSeconds(forwarend) && p.State == (short)IssueState.Normal).OrderBy(p=>p.EndTime).Select(p=>p.ID).Take(maxchasetask));

            if (details.Any(p => !issues.Contains(p.IssueID)))
                throw new ValidateException("无效的期号");

            var ratio = CacheManage.Ratio[task.ConsumptionRatio];
            if (ratio.State == (short)ConsumeRatioState.Locked)
                throw new ValidateException(ratio.Name + "模式已经停止使用！");
            var winmodel = CacheManage.WinModel[task.WinModelID];
            if (winmodel.State == (short)WinMoneyModelState.Locked)
                throw new ValidateException(winmodel.Name + "模式已经停止使用！");


            var playOptions = new PlayTypeOptionManage().GetUserOptionByRatio(task.UserID, task.LotteryID, task.WinModelID, task.ConsumptionRatio);
            var backToWinEnable = CacheManage.OptionSite[Option_Site_Key.Site_BackMoneyToWinMoney_Enable].ToBool(false);

            var fc = Arithmetic.LotteryFactory.CreateLottery((LotteryType)task.LotteryID);

            List<AddDetailItem> chases = new List<AddDetailItem>();

            foreach (var item in plays)
            {
                var tp = fc.GetPlayType((PlayType_E)item.PlayType.PlayTypeListID);
                var num = tp.RegistNum(item.ChoseNumber);
                if (string.IsNullOrEmpty(num))
                    throw new ValidateException(((PlayType_E)item.PlayType.PlayTypeListID).GetName() + "号码格式不正确：" + item.ChoseNumber);
                item.Count = tp.GetNumCount(item.ChoseNumber);
                item.Money = item.Count * ratio.RadixMoney;
            }

            var items = plays.Select(p => new ChaseTaskNumberItem
                {
                    PlayTypeID = p.PlayType.ID,
                    PlayListID = p.PlayType.PlayTypeListID,
                    Number = p.ChoseNumber,
                    IsCompound = p.IsCompound,
                    Count = p.Count,
                    Money = (double)p.Money,
                    BackMoneyToWinMoney = p.BackMoneyToWinMoney / 100,
                });

            task.ChoseNumber = BuildChaseTaskNumber(items);
            task.TaskMoney = 0;
            decimal playmoney = plays.Sum(p => p.Money);
            foreach (var item in details)
            {
                var chase = new AddDetailItem
                {
                    ChaseTaskID = task.ID,
                    IssueID = item.IssueID,
                    Multiple = item.Multiple,
                    Money = playmoney * item.Multiple,
                    Share = item.Share,
                    UserChoseShare = item.UserChoseShare,
                };
                task.TaskMoney += chase.Money;
                chases.Add(chase);
            }
            task.ChaseCount = chases.Count;

            if (user.Account.Balance < task.TaskMoney)
                throw new ValidateException("余额不足");

            plays.GroupBy(p => p.PlayTypeID).Each(pItem =>
            {
                var playType = CacheManage.PlayType[pItem.Key];
                var playTypeEnum = (PlayType_E)playType.PlayTypeListID;
                var playTypeProduct = fc.GetPlayType(playTypeEnum);

                if (playType.MaxBuyCount.HasValue && pItem.Sum(p1 => p1.Count) > playType.MaxBuyCount)
                    throw new ValidateException(string.Format(@"""{0}"" 最多只能购买 {1} 注", playType.PlayTypeList.Name,playType.MaxBuyCount));
                if (playType.MaxBuyMultiple.HasValue && details.Any(p1 => p1.Multiple > playType.MaxBuyMultiple))
                    throw new ValidateException(string.Format(@"""{0}""最多只能购买 {1} 倍", playType.PlayTypeList.Name, playType.MaxBuyMultiple));
                int num;
                var maxnumber = playType.MaxBuyNumber.Split(',').Select(p1 => int.TryParse(p1, out num) ? num : -1).ToArray();
                
                List<string>[] nums = maxnumber.Select(p1 => new List<string>()).ToArray();
                pItem.Each(p1 =>
                {
                    playTypeProduct.GetChoseNumberList(p1.ChoseNumber).Each(pp =>
                    pp.Split(',').Each((p2, j) =>
                    {
                        var t = p2.Select(p3 => p3.ToString());
                        if (t.Contains(",") || t.Contains(" "))
                            t = p2.Split(new char[] { ',', ' ' });
                        t.Each(p3 => { if (!nums[j].Contains(p3))nums[j].Add(p3); });
                    }));
                });
                nums.Each((p1, j) =>
                    {
                        if (maxnumber[j] >= 0 && p1.Count > maxnumber[j])
                            throw new ValidateException(string.Format(@"""{0}""第 {1} 位最多只能买 {2} 个号码", playTypeEnum.GetName(), j + 1, maxnumber[j]));
                    });
                
                if (!string.IsNullOrEmpty(playType.RestrictiveNumber))
                {
                    var res = new List<string>();
                    var r = playType.RestrictiveNumber.Split('|');
                    var b = new List<string>();
                    pItem.Each(p1 => b.AddRange(playTypeProduct.GetChoseNumberList(p1.ChoseNumber)));
                    r.Each(p1 => res.AddRange(playTypeProduct.GetChoseNumberList(p1).Where(p2 => b.Contains(p2))));
                    if (res.Count > 0)
                        throw new BetValidateException(string.Format(@"""{0}"" 不能投注：{1}", playTypeEnum.GetName(), string.Join("、", res.Distinct().ToArray())));
                }

                var playOpt = playOptions.First(pp => pp.PlayTypeID == pItem.Key);
                pItem.Each(item =>
                {
                    if (backToWinEnable && item.BackMoneyToWinMoney.HasValue)
                    {
                        if (item.BackMoneyToWinMoney < 0)
                            throw new BetValidateException("参数不正确");
                        else if ((double)item.BackMoneyToWinMoney.Value > playOpt.MaxBackMoneyToWinMoney)
                            throw new BetValidateException(string.Format("\"{0}\" 返点加奖最多：{1}%", playTypeEnum.GetName(), playOpt.MaxBackMoneyToWinMoney));
                    }
                    else if (item.BackMoneyToWinMoney.HasValue)
                    {
                        throw new BetValidateException("不能使用返点加奖功能");
                    }
                });
            });
            
            base.BeginTransaction();
            base.Insert(new
            {
                task.ID,
                task.LotteryID,
                task.ConsumptionRatio,
                task.ChaseCount,
                CancleCount=0,
                ExecuteCount=0,
                task.StopWin,
                task.UserID,
                task.WinModelID,
                task.ChoseNumber,
                task.TaskMoney
            });
            base.Update<Account>(new { Balance = new OpteratorValue(Opterator.Subtract, task.TaskMoney) }, new { UserID = user.ID });
            base.Insert<ChaseTask_Detail>(chases.ToArray());

            rs = base.ExecuteTransaction(chases.Count + 2);
            if (rs > 0)
            {
                try
                {
                    ExecChaseTask(task.ID);
                }
                catch (Exception e)
                {
                    string errormsg;
                    if (e is AppException)
                        errormsg = "追号:" + e.Message;
                    else
                        errormsg = "追号:系统错误";

                    if (Log.IsDebugEnabled)
                        Log.Error(errormsg, e);
                    else if (Log.IsErrorEnabled)
                        Log.Error(errormsg);
                }
            }

            return rs;
        }

        /// <summary>
        /// 追号 执行追号任务 ,撤销过期未执行的任务
        /// </summary>
        public void Exec(LotteryType lottery)
        {
            var tasks = base.Select<ChaseTask_Detail, IEnumerable<Guid>>(s => s
                .Where(p => p.State == (short)ChaseTaskState.Normal && p.Issue.StartTime <= DateTime.Now && p.Issue.EndTime > DateTime.Now && p.Issue.LotteryID==(int)lottery)
                .Select(p=>p.ChaseTaskID));
            int count =0, error = 0;
            tasks.Each(p =>
                {
                    try
                    {
                        count++;
                        int rs=ExecChaseTask(p);
                        if (rs < 0)
                            error++;
                    }
                    catch (Exception e)
                    {
                        string errormsg;
                        if (e is AppException)
                            errormsg = "追号:" + e.Message;
                        else
                            errormsg = "追号:系统错误";

                        if (Log.IsDebugEnabled)
                            Log.Error(errormsg, e);
                        else if (Log.IsErrorEnabled)
                            Log.Error(errormsg);
                    }
                });
            if(count>0&&Log.IsInfoEnabled)
                Log.InfoFormat("追号任务：任务 {0} 个，成功 {1} 个、失败 {2} 个！", count, count - error, error);
            if(CacheManage.OptionSite[Option_Site_Key.Site_Lottery_AutoCancleTimeOutChaseTask].ToBool(false))
                CancelTimeOutTask();
        }

        /// <summary>
        /// 执行指定的追号任务 (大于0为成功，小于0为失败，等于0为无该期任务)
        /// </summary>
        /// <exception cref="System.ArgumentOutOfRangeException"/>
        /// <exception cref="Code.Models.ValidateException"/>
        /// <exception cref="Code.Models.AppException"/>
        public int ExecChaseTask(Guid id)
        {
            var task = base.Select(s => s.FirstOrDefault(p => p.ID == id));

            if (task == null)
                throw new AppException("不存在该任务");

            var taskDetail = base.Select<ChaseTask_Detail, ChaseTask_Detail>(s => s.FirstOrDefault(p => p.ChaseTaskID == task.ID && p.Issue.StartTime <= DateTime.Now && p.Issue.EndTime > DateTime.Now));

            if (taskDetail == null)
                return 0;

            if (taskDetail.State != (short)ChaseTaskState.Normal)
                throw new ValidateException("该期任务已为" + ((ChaseTaskState)taskDetail.State).GetName());


            if (taskDetail.Share != 1)
                throw new AppException("追号任务:未实现合买功能 任务：" + taskDetail.ID + " 份数:" + taskDetail.Share + "！");
            
            taskDetail.SchemeID = Guid.NewGuid();
            
            var plays = ParseChaseTaskNumber(task.ChoseNumber)
                .Select(p => new
                    {
                        taskDetail.SchemeID,
                        p.PlayTypeID,
                        ChoseNumber = p.Number,
                        p.IsCompound,
                        p.Count,
                        Money = (decimal) (p.SingleMoney * taskDetail.Multiple),
                        p.BackMoneyToWinMoney,
                    }).ToArray();

            var scheme = new
            {
                ID = taskDetail.SchemeID,
                taskDetail.IssueID,
                taskDetail.Multiple,
                taskDetail.Share,
                task.ConsumptionRatio,
                SchemeMoney = taskDetail.Money,
                SchemeCount = plays.Sum(p=>p.Count),
                task.UserID,
                task.WinModelID,
                IsChaseTask=true,
                task.LotteryID
            };

            if (plays.Sum(p => p.Money) != scheme.SchemeMoney)
                throw new ValidateException(string.Format("追号任务:{3} 参数异常，倍数:{0} 注数:{1} 金额:{2}", scheme.Multiple, scheme.SchemeCount, scheme.SchemeMoney, taskDetail.ID));

            base.BeginTransaction();
            base.Insert<Scheme>(scheme);
            base.Insert<Scheme_Detail>(plays);
            base.Update<ChaseTask_Detail>(new { taskDetail.SchemeID, State = (short)ChaseTaskState.Executed }, new { taskDetail.ID, taskDetail.State });
            base.Update(new { ExecuteCount = new OpteratorValue(Opterator.Add, 1) }, new { task.ID, task.State });
            int rs = base.ExecuteTransaction(plays.Length + 3);
            if (rs > 0)
                CheckDetailComplete(task.ID);
            else if (Log.IsInfoEnabled)
                Log.InfoFormat("追号:追号明细{0}执行失败！", taskDetail.ID);
            return rs;
        }

        /// <summary>
        /// 撤销追号任务,只能撤消未执行的
        /// </summary>
        /// <param name="task">要撤销的任务</param>
        /// <param name="state">要撤销为哪种状态</param>
        /// <exception cref="System.ArgumentOutOfRangeException"/>
        /// <exception cref="Code.Models.AppException"/>
        public int CancelTask(Guid id, ChaseTaskState state)
        {
            var cs = new ChaseTaskState[] { ChaseTaskState.SysCancel, ChaseTaskState.TimeOutCancel, ChaseTaskState.UserCancel, ChaseTaskState.WinCancel };

            var task = base.Select(s => s.FirstOrDefault(p => p.ID == id));
            if (task == null)
                throw new AppException("不存在该任务");
            if (task.State == (short)ChaseTaskState.Executed)
                throw new ValidateException("该任务已完成");
            if (!cs.Contains(state))
                throw new ArgumentOutOfRangeException("state", "不支持的撤销状态");
            if (cs.Contains((ChaseTaskState)task.State))
                throw new ValidateException("该任务已为" + ((ChaseTaskState)task.State).GetName());

            var chasedetails = base.Select<ChaseTask_Detail, IEnumerable<decimal>>(s => s.Where(p => p.ChaseTaskID == task.ID && p.State == (short)ChaseTaskState.Normal).Select(p => p.Money)).ToArray();

            int upcount = 0;
            base.BeginTransaction();
            base.Update(new { State = (short)state, StopTime = DateTime.Now, CancleCount = new OpteratorValue(Opterator.Add, chasedetails.Length) }, new { task.ID, task.State });
            upcount++;
            if (chasedetails.Length > 0)
            {
                base.Update<ChaseTask_Detail>(new { State = (short)state }, new { State = (short)ChaseTaskState.Normal, ChaseTaskID = task.ID });
                var backmoney = chasedetails.Sum();
                base.Insert<OtherMoneyDetail>(new {task.UserID, Type = (short)OtherMoneyDetailType.ChaseTaskCancle, Money = backmoney, Memo = state.GetName(), Remark = string.Format("RefID:{0}", task.ID) });
                base.Update<Account>(new { Balance = new OpteratorValue(Opterator.Add, backmoney) }, new { task.UserID });
                upcount += chasedetails.Length + 2;
            }
            int rs = base.ExecuteTransaction(upcount);
            if (rs < 0 && Log.IsErrorEnabled)
                Log.ErrorFormat("追号:撤销追号任务{0}失败！", task.ID);
            return rs;
        }
        
        /// <summary>
        /// 撤消追号明细任务,只能撤消未执行的
        /// </summary>
        /// <param name="id">要撤消的明细任务</param>
        /// <param name="state">要撤销为哪种状态</param>
        /// <exception cref="System.ArgumentOutOfRangeException"/>
        /// <exception cref="Code.Models.AppException"/>
        public int CancelDetail(long id, ChaseTaskState state)
        {
            var cs = new ChaseTaskState[] { ChaseTaskState.SysCancel, ChaseTaskState.TimeOutCancel, ChaseTaskState.UserCancel, ChaseTaskState.WinCancel };

            var detail = base.Tables.ChaseTask_Detail.Select(p => new { p.State,p.ChaseTask.UserID,p.ChaseTaskID,p.Money,p.ID}).FirstOrDefault(p => p.ID == id);
            if (detail == null)
                throw new AppException("不存在该追号");
            if (!cs.Contains(state))
                throw new ArgumentOutOfRangeException("state", "不支持的撤销状态");
            if (detail.State == (short)ChaseTaskState.Executed)
                throw new ValidateException("该任务已执行,不能撤销");
            if (cs.Contains((ChaseTaskState)detail.State))
                throw new ValidateException("该任务已为" + ((ChaseTaskState)detail.State).GetName());

            base.BeginTransaction();
            base.Update<ChaseTask_Detail>(new { State = (short)state }, new { detail.ID, detail.State });
            base.Update(new { CancleCount = new OpteratorValue(Opterator.Add, 1) }, new { ID = detail.ChaseTaskID });
            base.Insert<OtherMoneyDetail>(new { detail.UserID, Type = (short)OtherMoneyDetailType.ChaseDetailCancle, Money = detail.Money, Memo = state.GetName(), Remark = string.Format("RefID:{0}&TaskID:{1}", detail.ID,detail.ChaseTaskID) });
            base.Update<Account>(new { Balance = new OpteratorValue(Opterator.Add, detail.Money) }, new { detail.UserID });
            int rs = base.ExecuteTransaction(4);
            if(rs>0)
                CheckDetailComplete(detail.ChaseTaskID);
            else if (rs < 0 && Log.IsErrorEnabled)
                Log.ErrorFormat("追号:撤销追号明细{0}失败！", detail.ID);
            
            return rs;
        }

        /// <summary>
        /// 撤消过期未执行的明细任务
        /// </summary>
        public void CancelTimeOutTask()
        {
            var details = base.Select<ChaseTask_Detail, IEnumerable<long>>(s => s.Where(p => p.State == (short)ChaseTaskState.Normal && p.Issue.EndTime < DateTime.Now).Select(p=>p.ID));

            details.Each(p => CancelDetail(p, ChaseTaskState.TimeOutCancel));
        }

        /// <summary>
        /// 更新追号任务状态
        /// </summary>
        /// <param name="taskid">追号任务ID</param>
        public int CheckDetailComplete(Guid taskid)
        {
            var noexec = base.Select<ChaseTask_Detail, int>(s => s.Where(p => p.ChaseTaskID == taskid && p.State == (short)ChaseTaskState.Normal).Count());
            if (noexec == 0)
            {
                noexec = base.Update(new { State = (short)ChaseTaskState.Executed, StopTime = DateTime.Now }, new { ID=taskid, State = (short)ChaseTaskState.Normal });
                if (noexec < 1 && Log.IsErrorEnabled)
                    Log.ErrorFormat("追号:追号任务{0}完成，但更新状态时出错。", taskid);
            }
            return noexec;
        }

        /// <summary>
        /// 生成追号任务号码
        /// </summary>
        public string BuildChaseTaskNumber(IEnumerable<ChaseTaskNumberItem> plays)
        {
            //PlayType:1&PlayTypeList:1&Number:0,1,2&IsCompound:1&Count:1&SingleMoney:2&BackMoneyToWinMoney:1.5    注：SingleMoney为Count*单倍金额
            var str = string.Join("\r\n", plays.Select(p => string.Format("PlayType:{0}&PlayList:{1}&Number:{2}&IsCompound:{3}&Count:{4}&SingleMoney:{5}&BackMoneyToWinMoney:{6}",
                p.PlayTypeID, p.PlayListID, p.Number, p.IsCompound, p.Count, p.Money, p.BackMoneyToWinMoney)).ToArray());

            str = Convert.ToBase64String(Encoding.UTF8.GetBytes(str));

            return str;
        }
        /// <summary>
        /// 解析追号任务号码
        /// </summary>
        public IEnumerable<ChaseTaskNumberItem> ParseChaseTaskNumber(string number)
        {
            IList<ChaseTaskNumberItem> rs = new List<ChaseTaskNumberItem>();
            if(!string.IsNullOrEmpty(number))
            {
                //PlayType:1&PlayTypeList:1&Number:0,1,2&IsCompound:1&Count:1&SingleMoney:2&BackMoneyToWinMoney:1.5    注：SingleMoney为Count*单倍金额
                var str = Encoding.UTF8.GetString(Convert.FromBase64String(number));
                rs = str.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries)
                    .Select(p =>
                    {
                        var temp = p.Split('&').ToDictionary(pp => pp.Split(':')[0], pp => pp.Split(':')[1]);
                        int playType = int.Parse(temp["PlayType"]);
                        var playlist = int.Parse(temp["PlayList"]);

                        decimal? backToWin = null;
                        if (temp.ContainsKey("BackMoneyToWinMoney") && !string.IsNullOrEmpty(temp["BackMoneyToWinMoney"]))
                            backToWin = decimal.Parse(temp["BackMoneyToWinMoney"]);

                        return new ChaseTaskNumberItem
                        {
                            PlayListID = playlist,
                            PlayTypeID = playType,
                            PlayName = CacheManage.Playlist.Values.First(pp => pp.ID == playlist).Name,
                            Number = temp["Number"],
                            IsCompound = short.Parse(temp["IsCompound"]),
                            Count = int.Parse(temp["Count"]),
                            SingleMoney = double.Parse(temp["SingleMoney"]),

                            BackMoneyToWinMoney = backToWin,
                        };
                    }).ToList();
            }
            return rs;
        }

        /// <summary>
        /// 获取当前用户的所有追号任务
        /// </summary>
        /// <param name="uid"></param>
        /// <param name="search"></param>
        /// <param name="paramList"></param>
        /// <returns></returns>
        public IEnumerable<ChaseTask> ChaseTaskList(Guid uid, string search = null, object[] paramList = null)
        {
            return base.Select(s => s.Where(p => p.UserID == uid).Where(string.IsNullOrEmpty(search) ? " 1==1 " : search, paramList ?? new object[0]).OrderByDescending(p => p.AddTime));
        }

        /// <summary>
        /// 获取当前用户的当前追号任务的追号明细
        /// </summary>
        /// <param name="uid"></param>
        /// <param name="chaseTaskID"></param>
        /// <param name="search"></param>
        /// <param name="paramList"></param>
        /// <returns></returns>
        public IEnumerable<ChaseDetail_Mod> ChaseTaskDetailList(Guid uid, Guid chaseTaskID, string search = null, object[] paramList = null)
        {
            return base.Select<ChaseTask_Detail, IEnumerable<ChaseDetail_Mod>>(s => s.Where(p => p.ChaseTaskID == chaseTaskID && (p.ChaseTask.UserID == uid||p.ChaseTask.Users.Commands.Contains(uid.ToString()))).OrderBy(p=>p.ID)
                .Where(search ?? " 1==1 ", paramList ?? new object[0]).Select(p => new ChaseDetail_Mod
                {
                    ID=p.ID,
                    ChaseTaskID=p.ChaseTaskID,
                    SchemeID=p.SchemeID,
                    Money=(double)p.Money,
                    Multiple=p.Multiple,
                    IssueNumber=p.Issue.Number,
                    State=p.State,
                    OpenCode=p.Issue.OpenCode
                }));
        }

        private class AddDetailItem
        {
            public Guid ChaseTaskID { get; set; }
            public long IssueID { get; set; }
            public int Multiple { get; set; }
            public decimal Money { get; set; }
            public int Share { get; set; }
            public int UserChoseShare { get; set; }
        }

        /// <summary>
        /// 获取追号任务（Name字段的需要自行设置）
        /// </summary>
        public IEnumerable<ChaseTaskItem> GetChaseTasks(ChaseTaskSerchModel serch, Guid? loginUid)
        {
            var rs = base.Tables.ChaseTask.Select(p => new ChaseTaskItem 
            {
                ID=p.ID,UserName=p.Users.LoginName,UserID=p.UserID,State=(ChaseTaskState)p.State,AddTime=p.AddTime,CancleCount=p.CancleCount,
                ExecuteCount=p.ExecuteCount,ChaseCount=p.ChaseCount,Commands=p.Users.Commands,ChooseNumber=p.ChoseNumber,
                Ratio=p.ConsumptionRatio,WinModel=p.WinModelID,StopWin=p.StopWin,TaskMoney=p.TaskMoney,StopTime=p.StopTime,LotteryType=(LotteryType)p.LotteryID
            });

            if (loginUid.HasValue)
                rs = rs.Where(p => p.Commands.Contains(loginUid.Value.ToString()) || p.UserID == loginUid);
            if (serch == null)
                return rs;

            if (serch.ID.HasValue)
                rs = rs.Where(p => p.ID == serch.ID);
            if (!string.IsNullOrEmpty(serch.UserName))
                rs = rs.Where(p => p.UserName == serch.UserName);
            if (serch.LotteryType.HasValue)
                rs = rs.Where(p => p.LotteryType == serch.LotteryType);
            if (serch.Ratio.HasValue)
                rs = rs.Where(p => p.Ratio == serch.Ratio);
            if (serch.WinModel.HasValue)
                rs = rs.Where(p => p.WinModel == serch.WinModel);
            if (serch.State.HasValue)
                rs = rs.Where(p => p.State == serch.State);
            if (serch.CommandID.HasValue)
                rs = rs.Where(p => p.Commands.Contains(serch.CommandID.ToString()));
            if (serch.StartTime.HasValue)
                rs = rs.Where(p => p.AddTime >= serch.StartTime.Value.Date);
            if (serch.EndTime.HasValue)
                rs = rs.Where(p => p.AddTime < serch.EndTime.Value.AddDays(1).Date);
            if (serch.StopWin.HasValue && serch.StopWin >= 0)
                rs = rs.Where(p => p.StopWin >= serch.StopWin);
            else if (serch.StopWin.HasValue)
                rs = rs.Where(p => p.StopWin <= serch.StopWin);

            return rs;
        }

        /// <summary>
        /// 获取追号任务明细（Name字段的需要自行设置，期号也要自行转换）
        /// </summary>
        public IEnumerable<ChaseTaskDetailItem> GetChaseTaskDetail(Guid id,Guid? loginUid)
        {
            var s=base.Tables.ChaseTask_Detail.Where(p=>p.ChaseTaskID==id);
            if (loginUid.HasValue)
                s = s.Where(p => p.ChaseTask.Users.Commands.Contains(loginUid.ToString()) || p.ChaseTask.UserID == loginUid);
            IEnumerable<ChaseTaskDetailItem> rs = s.Select(p => new ChaseTaskDetailItem
            {
                ID = p.ID,
                ChaseTaskID = id,
                IssueID = p.IssueID,
                IssueName = p.Issue.Number,
                SchemeID = p.SchemeID,
                Share = p.Share,
                State = (ChaseTaskState)p.State,
                ExecTime = p.Scheme.AddTime,
                Money = p.Money,
                Multiply = p.Multiple,
                UserChoseShare = p.UserChoseShare,
                LotteryType = (LotteryType)p.Issue.LotteryID,
                IsTimeNow = (p.Issue.EndTime > DateTime.Now && p.Issue.StartTime < DateTime.Now),
                OpenCode=p.Issue.OpenCode
            });
            return rs;
        }


        [Serializable]
        public class ChaseTaskItem
        {
            public Guid ID { get; set; }
            public Guid UserID { get; set; }
            public string UserName { get; set; }
            public string Commands { get; set; }
            public int WinModel { get; set; }
            public decimal Ratio { get; set; }
            public string WinModelName { get; set; }
            public string RatioName { get; set; }
            public LotteryType LotteryType { get; set; }
            public string ChooseNumber { get; set; }
            public decimal TaskMoney { get; set; }
            public decimal StopWin { get; set; }
            public int ChaseCount { get; set; }
            public int ExecuteCount { get; set; }
            public int CancleCount { get; set; }
            public ChaseTaskState State { get; set; }
            public DateTime AddTime { get; set; }
            public DateTime? StopTime { get; set; }
        }

        [Serializable]
        public class ChaseTaskDetailItem
        {
            public long ID { get; set; }
            public Guid ChaseTaskID { get; set; }
            public long IssueID { get; set; }
            public string IssueName{get;set;}
            public Guid? SchemeID { get; set; }
            public int Multiply { get; set; }
            public decimal Money { get; set; }
            public int Share { get; set; }
            public int UserChoseShare { get; set; }
            public DateTime? ExecTime { get; set; }
            public ChaseTaskState State { get; set; }
            public LotteryType LotteryType { get; set; }
            /// <summary>
            /// 是否是当前期
            /// </summary>
            public bool IsTimeNow { get; set; }
            /// <summary>
            /// 开奖号码
            /// </summary>
            public string OpenCode { get; set; }
        }

        [Serializable]
        public class ChaseTaskNumberItem
        {
            public int PlayTypeID { get; set; }
            public int PlayListID { get; set; }
            public string PlayName { get; set; }
            public short IsCompound { get; set; }
            public string Number { get; set; }
            public int Count { get; set; }
            /// <summary>
            /// 单倍金额
            /// </summary>
            public double SingleMoney { get; set; }
            /// <summary>
            /// 自行设置，用单倍金额*倍数
            /// </summary>
            public double Money { get; set; }

            public decimal? BackMoneyToWinMoney { get; set; }
        }

        [Serializable]
        public class ChaseTaskSerchModel
        {
            public Guid? ID { get; set; }
            public DateTime? StartTime { get; set; }
            public DateTime? EndTime { get; set; }
            public LotteryType? LotteryType { get; set; }
            public string UserName { get; set; }
            public Guid? CommandID { get; set; }
            public ChaseTaskState? State { get; set; }
            public decimal? Ratio { get; set; }
            public int? WinModel { get; set; }
            public decimal? StopWin { get; set; }
        }
    }
}
